package com.steel.yfmall.cloud.assistant.goods.impl;

import com.alibaba.fastjson.JSON;
import com.steel.yfmall.cloud.assistant.bean.AssistantConstants;
import com.steel.yfmall.cloud.assistant.common.CacheRedisService;
import com.steel.yfmall.cloud.assistant.dto.para.goods.ParaSteelProductPriceFormBean;
import com.steel.yfmall.cloud.assistant.goods.ProductPriceFormFactorService;
import com.steel.yfmall.cloud.assistant.goods.ProductPriceFormService;
import com.steel.yfmall.cloud.assistant.dto.para.goods.ParaProductPriceFormBean;
import com.steel.yfmall.cloud.assistant.dto.zg.price.*;
import com.steel.yfmall.cloud.assistant.goods.mapper.SteelProductPriceBeanMapper;
import com.steel.yfmall.cloud.assistant.po.goods.SteelProductPriceBean;
import com.steel.yfmall.cloud.assistant.po.goods.SteelProductPriceBeanExample;
import com.steel.yfmall.cloud.assistant.po.goods.SteelProductPriceFormBean;
import com.steel.yfmall.cloud.assistant.po.goods.SteelProductPriceFormFactorDatailsBean;
import com.steel.yfmall.cloud.components.mq.bean.RequestSendMQBean;
import com.steel.yfmall.cloud.components.mq.service.MqSendService;
import com.steel.yfmall.cloud.components.utils.base.APIMsgBean;
import com.steel.yfmall.cloud.components.utils.base.ResponseCode;
import com.steel.yfmall.cloud.components.utils.base.SOAStateBean;
import com.steel.yfmall.cloud.components.utils.utils.UtilDate;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author yuchaohua
 * @version V1.0
 * @Title: ProductPriceFormServiceImpl
 * @Package com.steel.yfmall.cloud.assistant.biz.service.goods.impl
 * @Description: (用一句话描述该文件做什么)
 * @date 2020/12/5 11:12
 */
@Slf4j
@Service
public class ProductPriceFormServiceImpl implements ProductPriceFormService {

    @Resource
    private SteelProductPriceBeanMapper steelProductPriceBeanMapper;

    @Resource
    private ProductPriceFormFactorService productPriceFormFactorService;

    @Resource
    private MqSendService mqSendService;

    @Resource
    private CacheRedisService cacheRedisService;


    /**
     * key
     * @param paraBean
     * @return
     */
    public String getSteelProductPriceFromInfoListKey(ParaSteelProductPriceFormBean paraBean){
        Map<String, Serializable> params = new HashMap<>();
        params.put("siteCode", AssistantConstants.DEFALUT_SITECODE);
        params.put("paraBean", paraBean);
        // 在redis中获取值
        return cacheRedisService.generatorIndex("getSteelProductPriceFromInfoList", params);
    }


    /**
     * key
     * @param paraBean
     * @return
     */
    public String getSteelProductPriceInfoKey(ParaSteelProductPriceFormBean paraBean){
        Map<String, Serializable> params = new HashMap<>();
        params.put("siteCode", AssistantConstants.DEFALUT_SITECODE);
        if(paraBean != null){
            params.put("priceType", paraBean.getPriceType());
            params.put("priceClassify", paraBean.getPriceClassify());
        }
        // 在redis中获取值
        return cacheRedisService.generatorIndex("getSteelProductPriceInfo", params);
    }

    /**
     * 价格同步后清空对应的价格缓存
     * @param paraBean
     */
    public void delPriceFormRedis(ParaSteelProductPriceFormBean paraBean){
        // 价格主信息
        String steelProductPriceInfoKey = getSteelProductPriceInfoKey(paraBean);
        if (StringUtils.isNotBlank(steelProductPriceInfoKey)){
            cacheRedisService.delCommonStringData(steelProductPriceInfoKey);
        }

        // 价格组成信息
        String steelProductPriceFromInfoListKey = getSteelProductPriceFromInfoListKey(paraBean);
        if (StringUtils.isNotBlank(steelProductPriceFromInfoListKey)){
            cacheRedisService.delCommonStringData(steelProductPriceFromInfoListKey);
        }
    }

    /**
     * 同步多维度价格信息
     * @Title: batchTemplateProductPriceFactor
     * @Description: (这里用一句话描述这个方法的作用)
     * @Param priceEffectBean 参数说明
     * @return com.steel.yfmall.cloud.components.utils.base.APIMsgBean<java.lang.Boolean>    返回类型
     * @author yuchaohua
     * @date 2020/12/7 22:40
     */
    @Override
    public APIMsgBean<Boolean>  batchTemplateProductPriceFactor(PriceEffectBean priceEffectBean) {
        APIMsgBean<Boolean> apiMsgBean = new APIMsgBean<>();
        apiMsgBean.setData(false);
        // 判断是否有主信息
        if (priceEffectBean == null || priceEffectBean.getSr051vo() == null) {
            apiMsgBean.setSoaStateBean(ResponseCode.buildEnumErrorSOAStateBean("sr051vo 价格组成信息为空"));
            return apiMsgBean;
        }
        try {
            Sr051voBean sr051voBean = priceEffectBean.getSr051vo();
            Map<String, String> checkMap = new HashMap<>();
            checkMap.put("priceType", "价格类别");
            checkMap.put("priceClassify", "价格类型");
            SOAStateBean soaStateBean = ResponseCode.checkApiParameter(checkMap, sr051voBean);
            if (soaStateBean.getMessage() != null) {
                apiMsgBean.setSoaStateBean(soaStateBean);
                return apiMsgBean;
            }
            // 生效或失效类别  Y表示生效；N表示失效
            if (!StringUtils.equalsIgnoreCase(priceEffectBean.getType(), "Y")) {
                // 校验是否成功
                SteelProductPriceBean paraBean = new SteelProductPriceBean();
                paraBean.setPriceClassify(sr051voBean.getPriceClassify());
                paraBean.setPriceType(sr051voBean.getPriceType());
                paraBean.setStatus(1);
                SteelProductPriceBean resultProductPrice = getSteelProductPriceBeanByPara(paraBean);
                if (null != resultProductPrice) {
                    SteelProductPriceBean recordBean = new SteelProductPriceBean();
                    recordBean.setStatus(0);
                    recordBean.setVersion(sr051voBean.getVersion());
                    recordBean.setUpdateEmpNo(sr051voBean.getUnEffectEmpNo());
                    recordBean.setUnEffectEmpNo(sr051voBean.getUnEffectEmpNo());
                    if(StringUtils.isNotBlank(sr051voBean.getUnEffectDate()) && StringUtils.isNotBlank(sr051voBean.getUnEffectTime())){
                        recordBean.setUnEffectDate(UtilDate.getDateFromStr(sr051voBean.getUnEffectDate() + sr051voBean.getUnEffectTime()));
                    }
                    // 将价格修改为失效状态
                    updateSteelProductPriceBeanByPara(paraBean, recordBean);
                }
            } else {
                // 价格生效处理
                // key是 价格类别 + 价格分类 + 价格代码 `price_type`,`price_classify`,`price_code`
                HashMap<String, SteelProductPriceFormBean> productPriceFormMap = new HashMap<>();
                // 商品价格组成表数据处理
                String productPriceFormMsg = getProductPriceForm(priceEffectBean.getSr051vo(), productPriceFormMap, priceEffectBean.getSr061(), priceEffectBean.getSr062());
                // 价格具体组成因子和价格因子
                if (StringUtils.isNotBlank(productPriceFormMsg)) {
                    apiMsgBean.setSoaStateBean(ResponseCode.buildEnumErrorSOAStateBean(productPriceFormMsg));
                    return apiMsgBean;
                }
                // 判断是否有价格组成数据
                if (productPriceFormMap == null || productPriceFormMap.size() <= 0) {
                    apiMsgBean.setSoaStateBean(ResponseCode.buildEnumErrorSOAStateBean("缺少合法的价格组成数据"));
                    return apiMsgBean;
                }
                // key是 价格类别 + 价格分类 + 价格代码 `price_type`,`price_classify`,`price_code`
                HashMap<String, List<SteelProductPriceFormFactorDatailsBean>> productPriceFormFactorMap = new HashMap<>();
                // 商品价格组成表数据处理
                String productPriceFormFactorMsg = getProductPriceFormFactor(productPriceFormFactorMap, priceEffectBean.getSr063(), priceEffectBean.getSr064());
                // 价格具体组成因子和价格因子
                if (StringUtils.isNotBlank(productPriceFormFactorMsg)) {
                    apiMsgBean.setSoaStateBean(ResponseCode.buildEnumErrorSOAStateBean(productPriceFormFactorMsg));
                    return apiMsgBean;
                }
                // 判断是否有价格因子组成数据
                if (productPriceFormFactorMap == null || productPriceFormFactorMap.size() <= 0) {
                    apiMsgBean.setSoaStateBean(ResponseCode.buildEnumErrorSOAStateBean("缺少合法的价格因子组成数据"));
                    return apiMsgBean;
                }
                // 对价格数据进行新增和修改
                String insertOrUpdatePriceForm = insertOrUpdateSteelProductPriceBean(priceEffectBean.getSr051vo(), productPriceFormMap, productPriceFormFactorMap);
                if (StringUtils.isNotBlank(insertOrUpdatePriceForm)) {
                    apiMsgBean.setSoaStateBean(ResponseCode.buildEnumErrorSOAStateBean(productPriceFormFactorMsg));
                    return apiMsgBean;
                }
                // 如果同步过来的是指导价格，那么进行商品价格同步
               // if (StringUtils.equalsIgnoreCase(sr051voBean.getPriceClassify(), AssistantConstants.PRICE_CLASSIFY_A01)){
                    RequestSendMQBean requestSendMQBean = new RequestSendMQBean();
                    requestSendMQBean.setSendMqTitle("refresh_product_type_price");
                    requestSendMQBean.setSendMqMessage(JSON.toJSONString(sr051voBean));
                    mqSendService.sendCommonMQMessage(requestSendMQBean);
               // }
            }
            ParaSteelProductPriceFormBean paraSteelProductPriceFormBean = new ParaSteelProductPriceFormBean();
            paraSteelProductPriceFormBean.setPriceType(sr051voBean.getPriceType());
            paraSteelProductPriceFormBean.setPriceClassify(sr051voBean.getPriceClassify());
            paraSteelProductPriceFormBean.setStatus(1);
            // 清空价格缓存
            delPriceFormRedis(paraSteelProductPriceFormBean);
            // 新增成功
            apiMsgBean.setSoaStateBean(ResponseCode.buildEnumSuccessSOAStateBean());
            apiMsgBean.setData(true);
        } catch (Exception e) {
            log.error("价格同步出现异常：" + JSON.toJSONString(priceEffectBean), e);
            apiMsgBean.setSoaStateBean(ResponseCode.buildEnumSuccessSOAStateBean("价格同步失败"));
        }
        return apiMsgBean;
    }

    /**
     * 同步新增多维度价格
     * @param sr051vo
     * @param productPriceFormMap
     * @param productPriceFormFactorMap
     * @return
     */
    private String insertOrUpdateSteelProductPriceBean(Sr051voBean sr051vo, HashMap<String, SteelProductPriceFormBean> productPriceFormMap, HashMap<String, List<SteelProductPriceFormFactorDatailsBean>> productPriceFormFactorMap) {
        String returnMsg = "";
        if (sr051vo == null){
            return "价格主档信息不存在";
        }
        // 判断是否有价格组成数据
        if (productPriceFormMap == null || productPriceFormMap.size() <= 0) {
            return "缺少合法的价格组成数据";
        }
        // 判断是否有价格因子组成数据
        if (productPriceFormFactorMap == null || productPriceFormFactorMap.size() <= 0) {
            return "缺少合法的价格因子组成数据";
        }
        SteelProductPriceBean recordBean = new SteelProductPriceBean();
        recordBean.setSalesType(sr051vo.getSalesType());
        recordBean.setVersion(sr051vo.getVersion());
        recordBean.setUpdateEmpNo(sr051vo.getEffectEmpNo());
        recordBean.setEffectEmpNo(sr051vo.getEffectEmpNo());
        recordBean.setStatus(1);
        // 生效时间
        if(StringUtils.isNotBlank(sr051vo.getEffectDate()) && StringUtils.isNotBlank(sr051vo.getEffectTime())){
            recordBean.setEffectTime(UtilDate.getDateFromStr(sr051vo.getEffectDate() + sr051vo.getEffectTime()));
        }
        boolean priceStatus = false;
        SteelProductPriceBean paraBean = new SteelProductPriceBean();
        paraBean.setPriceClassify(sr051vo.getPriceClassify());
        paraBean.setPriceType(sr051vo.getPriceType());
        // 获取主档信息
        SteelProductPriceBean resultProductPrice = getSteelProductPriceBeanByPara(paraBean);
        if (null != resultProductPrice) {
            // 将价格修改为有效效状态
            priceStatus = updateSteelProductPriceBeanByPara(paraBean, recordBean);
        }else{
            recordBean.setPriceClassify(sr051vo.getPriceClassify());
            recordBean.setPriceType(sr051vo.getPriceType());
            // 将价格修改为失效状态
            priceStatus = insertSteelProductPriceBeanByPara(recordBean);
        }
        if (!priceStatus){
            return "价格主档信息异常无法添加";
        }
        // 如果有历史数据。那么进行删除操作
        if(resultProductPrice != null){
            ParaProductPriceFormBean paraProductPriceFormBean = new ParaProductPriceFormBean();
            paraProductPriceFormBean.setPriceClassify(sr051vo.getPriceClassify());
            paraProductPriceFormBean.setPriceType(sr051vo.getPriceType());
            productPriceFormFactorService.removeSteelProductPriceFormBeanByPara(paraProductPriceFormBean);
        }
        // 新增价格组成和价格因子
        for(Map.Entry<String, SteelProductPriceFormBean> formBeanHashMap : productPriceFormMap.entrySet()){
            String priceCode = formBeanHashMap.getKey();
            SteelProductPriceFormBean priceFormBean = formBeanHashMap.getValue();
            priceFormBean.setVersion(sr051vo.getVersion());
            int productPriceFormId = productPriceFormFactorService.insertSteelProductPriceFormBeanByPara(priceFormBean);
            // 匹配是否需要新增价格因子
            if (productPriceFormId > 0 && priceFormBean.getId() != null && productPriceFormFactorMap.containsKey(priceCode) && CollectionUtils.isNotEmpty(productPriceFormFactorMap.get(priceCode))){
                List<SteelProductPriceFormFactorDatailsBean> factorDatailsBeans = productPriceFormFactorMap.get(priceCode);
                // 处理价格组成ID
                for (SteelProductPriceFormFactorDatailsBean factorDetail : factorDatailsBeans) {
                    factorDetail.setProductPriceFormId(priceFormBean.getId());
                    factorDetail.setVersion(sr051vo.getVersion());
                    factorDetail.setCreateDate(UtilDate.getDate());
                    factorDetail.setUpdateDate(UtilDate.getDate());
                    factorDetail.setMemo(priceFormBean.getPriceType() + "_" + priceFormBean.getPriceClassify() + "_" + priceCode + "_" + priceFormBean.getId());
                    factorDetail.setStatus(1);
                }
                productPriceFormFactorService.batchInsertSteelProductPriceFormFactorDatailsBeanByPara(factorDatailsBeans);
            }
        }
        return returnMsg;
    }


    /**
     * 价格因子封装
     *
     * @param productPriceFormMap
     * @param sr063BeanList       价格因子设定
     * @param sr064BeanList       价格资料
     * @return
     */
    private String getProductPriceFormFactor(HashMap<String, List<SteelProductPriceFormFactorDatailsBean>> productPriceFormMap, List<Sr063Bean> sr063BeanList, List<Sr064Bean> sr064BeanList) {
        String productPriceFormMsg = "";
        if (CollectionUtils.isEmpty(sr063BeanList)) {
            productPriceFormMsg = "sr063 价格因子设定信息为空";
        }
        if (CollectionUtils.isEmpty(sr064BeanList)) {
            productPriceFormMsg = "sr064 价格资料信息为空";
        }
        if (StringUtils.isBlank(productPriceFormMsg)) {
            // 具体的价格决定因子 key 因子识别值
            Map<String, List<Sr063Bean>> sr063BeanListMap = new HashMap<>();
            for (Sr063Bean sr063Bean : sr063BeanList) {
                String keyId = sr063Bean.getId();
                sr063Bean.setId(null);
                if (sr063BeanListMap.containsKey(keyId)) {
                    sr063BeanListMap.get(keyId).add(sr063Bean);
                } else {
                    List<Sr063Bean> sr063Beans = new ArrayList<>();
                    sr063Beans.add(sr063Bean);
                    sr063BeanListMap.put(keyId, sr063Beans);
                }
            }
            // 具体的价格资料
            for (Sr064Bean sr064Bean : sr064BeanList) {
                String keyPriceCode = sr064Bean.getPriceCode();
                SteelProductPriceFormFactorDatailsBean formFactorDetailsBean = new SteelProductPriceFormFactorDatailsBean();
                formFactorDetailsBean.setJyjtProductPriceFormId(sr064Bean.getId());
                formFactorDetailsBean.setPrice(sr064Bean.getPrice());
                formFactorDetailsBean.setMemo(sr064Bean.getPriceCode());
                formFactorDetailsBean.setVersion(sr064Bean.getVersion());
                // 将价格诀别因子放入到价格资料组成里面
                if (sr063BeanListMap.containsKey(sr064Bean.getId())) {
                    formFactorDetailsBean.setProductPriceFormFactorDetail(JSON.toJSONString(sr063BeanListMap.get(sr064Bean.getId())));
                }
                if (productPriceFormMap.containsKey(keyPriceCode)) {
                    productPriceFormMap.get(keyPriceCode).add(formFactorDetailsBean);
                } else {
                    List<SteelProductPriceFormFactorDatailsBean> factorDatailsBeans = new ArrayList<>();
                    factorDatailsBeans.add(formFactorDetailsBean);
                    productPriceFormMap.put(keyPriceCode, factorDatailsBeans);
                }
            }
        }
        return productPriceFormMsg;
    }

    /**
     * 商品价格组成表数据处理
     *
     * @param sr051vo
     * @param productPriceFormMap
     * @param sr061BeanList       价格组成代码
     * @param sr062BeanList       价格組成因子
     * @return
     */
    private String getProductPriceForm(Sr051voBean sr051vo, HashMap<String, SteelProductPriceFormBean> productPriceFormMap, List<Sr061Bean> sr061BeanList, List<Sr062Bean> sr062BeanList) {
        String productPriceFormMsg = "";
        if (CollectionUtils.isEmpty(sr061BeanList)) {
            productPriceFormMsg = "sr061 价格组成代码信息为空";
        }
        if (CollectionUtils.isEmpty(sr062BeanList)) {
            productPriceFormMsg = "sr062 价格組成因子信息为空";
        }
        if (StringUtils.isBlank(productPriceFormMsg)) {
            // 具体的价格组成因子
            Map<String, List<Sr062Bean>> sr062BeanListMap = new HashMap<>();
            for (Sr062Bean sr062Bean : sr062BeanList) {
                String keyPriceCode = sr062Bean.getPriceCode();
                if (sr062BeanListMap.containsKey(keyPriceCode)) {
                    sr062BeanListMap.get(keyPriceCode).add(sr062Bean);
                } else {
                    List<Sr062Bean> sr062Beans = new ArrayList<>();
                    sr062Beans.add(sr062Bean);
                    sr062BeanListMap.put(keyPriceCode, sr062Beans);
                }
            }

            // 处理价格组成代码
            for (Sr061Bean sr061Bean : sr061BeanList) {
                String keyPriceCode = sr061Bean.getPriceCode();
                String keyName = sr061Bean.getPriceDesc();
                SteelProductPriceFormBean steelProductPriceFormBean = new SteelProductPriceFormBean();
                steelProductPriceFormBean.setPriceType(sr051vo.getPriceType());
                steelProductPriceFormBean.setPriceClassify(sr051vo.getPriceClassify());
                steelProductPriceFormBean.setPriceCode(keyPriceCode);
                steelProductPriceFormBean.setPriceName(keyName);
                // 将组成因子放入到组成里面
                if (sr062BeanListMap.containsKey(keyPriceCode)) {
                    steelProductPriceFormBean.setProductPriceFormFactor(JSON.toJSONString(sr062BeanListMap.get(keyPriceCode)));
                }
                steelProductPriceFormBean.setVersion(sr061Bean.getVersion());
                productPriceFormMap.put(keyPriceCode, steelProductPriceFormBean);
            }
        }
        return productPriceFormMsg;
    }

    /**
     * 查询单条价格主信息
     * @Title: getSteelProductPriceBeanByPara
     * @Description: (这里用一句话描述这个方法的作用)
     * @Param paraBean 参数说明
     * @return com.steel.yfmall.cloud.assistant.po.goods.SteelProductPriceBean    返回类型
     * @author yuchaohua
     * @date 2020/12/8 16:53
     */
    @Override
    public SteelProductPriceBean getSteelProductPriceBeanByPara(SteelProductPriceBean paraBean) {
        SteelProductPriceBeanExample example = new SteelProductPriceBeanExample();
        SteelProductPriceBeanExample.Criteria criteria = example.createCriteria();
        getProductPriceSearchDate(paraBean, criteria);
        return steelProductPriceBeanMapper.selectOneByExampleSelective(example);
    }

    /**
     * 修改价格主信息
     * @Title: updateSteelProductPriceBeanByPara
     * @Description: (这里用一句话描述这个方法的作用)
     * @Param paraBean 参数说明
     * @Param recordBean 参数说明
     * @return boolean    返回类型
     * @author yuchaohua
     * @date 2020/12/8 16:53
     */
    @Override
    public boolean updateSteelProductPriceBeanByPara(SteelProductPriceBean paraBean, SteelProductPriceBean recordBean) {
        if (paraBean == null || recordBean == null) {
            return false;
        }
        // 修改时间
        recordBean.setUpdateTime(UtilDate.getDate());
        SteelProductPriceBeanExample example = new SteelProductPriceBeanExample();
        SteelProductPriceBeanExample.Criteria criteria = example.createCriteria();
        getProductPriceSearchDate(paraBean, criteria);
        return steelProductPriceBeanMapper.updateByExampleSelective(recordBean, example) > 0;
    }


    /**
     * 新增价格主信息
     * @Title: insertSteelProductPriceBeanByPara
     * @Description: (这里用一句话描述这个方法的作用)
     * @Param recordBean 参数说明
     * @return boolean    返回类型
     * @author yuchaohua
     * @date 2020/12/8 16:54
     */
    @Override
    public boolean insertSteelProductPriceBeanByPara(SteelProductPriceBean recordBean) {
        if (recordBean == null || StringUtils.isBlank(recordBean.getPriceClassify()) || StringUtils.isBlank(recordBean.getPriceType())) {
            return false;
        }
        // 修改时间
        recordBean.setCreateTime(UtilDate.getDate());
        return steelProductPriceBeanMapper.insertSelective(recordBean) > 0;
    }

    /**
     * 价格主表信息sql条件拼接
     *
     * @param paraBean
     * @param criteria
     */
    private void getProductPriceSearchDate(SteelProductPriceBean paraBean, SteelProductPriceBeanExample.Criteria criteria) {
        if (paraBean == null || criteria == null) {
            return;
        }
        if (StringUtils.isNotBlank(paraBean.getPriceType())) {
            criteria.andPriceTypeEqualTo(paraBean.getPriceType());
        }
        if (StringUtils.isNotBlank(paraBean.getPriceClassify())) {
            criteria.andPriceClassifyEqualTo(paraBean.getPriceClassify());
        }
        if (null != paraBean.getStatus()) {
            criteria.andStatusEqualTo(paraBean.getStatus());
        }
        if (null != paraBean.getId()) {
            criteria.andIdEqualTo(paraBean.getId());
        }
    }

}
